package com.example.rpc_core.serializable.impl;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.example.rpc_core.serializable.Serializable;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class KryoSerializable implements Serializable {
        /**
         * kryo 线程不安全，使用 ThreadLocal 保证每个线程只有一个 Kryo
         */
        private static final ThreadLocal<Kryo> KRYO_THREAD_LOCAL = ThreadLocal.withInitial(() -> {
            Kryo kryo = new Kryo();
            // 设置动态动态序列化和反序列化类，不提前注册所有类（可能有安全问题）
            kryo.setRegistrationRequired(false);
            return kryo;
        });

        @Override
        public <T> byte[] serialize(T obj) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            Output output = new Output(byteArrayOutputStream);
            KRYO_THREAD_LOCAL.get().writeObject(output, obj);
            output.close();
            return byteArrayOutputStream.toByteArray();
        }

        @Override
        public <T> T deserialize(byte[] bytes, Class<T> classType) {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            Input input = new Input(byteArrayInputStream);
            T result = KRYO_THREAD_LOCAL.get().readObject(input, classType);
            input.close();
            return result;
        }
}


